package com.ochnas.volunteersignup.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.orm.jpa.support.JpaDaoSupport;

import com.ochnas.volunteersignup.domain.Event;
import com.ochnas.volunteersignup.domain.Position;
import com.ochnas.volunteersignup.domain.Time;
import com.ochnas.volunteersignup.domain.TimeSlot;
import com.ochnas.volunteersignup.domain.User;

public class EventServiceImpl extends JpaDaoSupport implements EventService {

	@Override
	public Event createEvent(Event e) {
		getJpaTemplate().persist(e);
		return e;
	}
	@Override
	public Position createPositionForEvent(Event e, String name,
			String description, int requiredNumberOfVolunteers) {
		Position p = new Position(name, description, requiredNumberOfVolunteers);
		getJpaTemplate().persist(p);
		
		e.addPosition(p);
		e = getJpaTemplate().merge(e);
		getJpaTemplate().persist(e);
		
		p = getJpaTemplate().merge(p);
		getJpaTemplate().persist(p);
		
		return p;
	}

	@Override
	public TimeSlot createTimeSlotForPosition(Position p, Time startTime,
			Time endTime, int quantityOfVolunteers) {
		TimeSlot ts = new TimeSlot(startTime, endTime, quantityOfVolunteers);
		getJpaTemplate().persist(ts);
		
		p.addTimeSlot(ts);
		p = getJpaTemplate().merge(p);
		getJpaTemplate().persist(p);
		
		ts = getJpaTemplate().merge(ts);
		getJpaTemplate().persist(ts);
		
		return ts;
	}

	@Override
	public void deleteEvent(Long eventId) {
		Event storedEvent = getJpaTemplate().find(Event.class, eventId);
		// need to delete volunteer assignment to the particular event first
		List resultList = getJpaTemplate().find("select f from FilledVolunteerRequisition f where f.event = ?", 
				storedEvent);
		for (Object o: resultList) {
			getJpaTemplate().remove(o);
		}
		getJpaTemplate().remove(storedEvent);
	}

	@Override
	public void deletePositionOfEvent(Long positionId) {
		Position storedPosition = getJpaTemplate().find(Position.class, positionId);
		Event storedEvent = getJpaTemplate().find(Event.class, storedPosition.getEvent().getId());
		List resultList = getJpaTemplate().find("select f from FilledVolunteerRequisition f where f.position = ?", 
				storedPosition);
		for (Object o: resultList) {
			getJpaTemplate().remove(o);
		}
		
		storedEvent.removePosition(storedPosition);
		storedEvent = getJpaTemplate().merge(storedEvent);
		getJpaTemplate().persist(storedEvent);
		getJpaTemplate().remove(storedPosition);
		
	}

	@Override
	public void deleteTimeSlotOfPosition(Long timeSlotId) {
		TimeSlot storedTimeSlot = getJpaTemplate().find(TimeSlot.class, timeSlotId);
		Position storedPosition = getJpaTemplate().find(Position.class, storedTimeSlot.getPosition().getId());
		List resultList = getJpaTemplate().find("select f from FilledVolunteerRequisition f where f.timeSlot = ?", 
				storedTimeSlot);
		for (Object o: resultList) {
			getJpaTemplate().remove(o);
		}
		storedPosition.removeTimeSlot(storedTimeSlot);
		storedPosition = getJpaTemplate().merge(storedPosition);
		getJpaTemplate().persist(storedPosition);
		getJpaTemplate().remove(storedTimeSlot);
	}

	@Override
	public Event updateEvent(Event e) {
		e = getJpaTemplate().merge(e);
		getJpaTemplate().persist(e);
		return e;
	}

	@Override
	public Position updatePositionOfEvent(Position p) {
		p = getJpaTemplate().merge(p);
		getJpaTemplate().persist(p);
		return p;
	}

	@Override
	public TimeSlot updateTimeSlotOfPosition(TimeSlot ts) {
		ts = getJpaTemplate().merge(ts);
		getJpaTemplate().merge(ts);
		return ts;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Event findEvent(Long eventId) {
		Event event = getJpaTemplate().find(Event.class, eventId);
		List positions = getJpaTemplate().find("select p from Position p where p.event =?", event);
		for (Object p: positions) {
			Position position = (Position) p;
			List timeSlots = getJpaTemplate().find("select t from TimeSlot t where t.position =?", position);
			position.setTimeSlots(timeSlots);
		}
		event.setPositions(positions);
		return event;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Event> findEventsByCoordinator(Long userId) {
		User storedUser = getJpaTemplate().find(User.class, userId);
		String queryString = "select e from Event e where e.coordinator = ?";
		List resultList = getJpaTemplate().find(queryString, storedUser);
		for (Object e: resultList) {
			Event event = (Event) e;
			List positions = getJpaTemplate().find("select p from Position p where p.event =?", event);
			for (Object p: positions) {
				Position position = (Position) p;
				List timeSlots = getJpaTemplate().find("select t from TimeSlot t where t.position =?", position);
				position.setTimeSlots(timeSlots);
			}
			event.setPositions(positions);
		}
		return resultList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Position findPosition(Long positionId) {
		Position position = getJpaTemplate().find(Position.class, positionId);
		List timeSlots = getJpaTemplate().find("select t from TimeSlot t where t.position =?", position);
		position.setTimeSlots(timeSlots);
		return position;
	}

	@Override
	public TimeSlot findTimeSlot(Long timeSlotId) {
		TimeSlot storedTimeSlot = getJpaTemplate().find(TimeSlot.class, timeSlotId);
		return storedTimeSlot;
	}

}
